package com.jzo2o.health.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.health.mapper.ReservationSettingMapper;
import com.jzo2o.health.model.domain.ReservationSetting;
import com.jzo2o.health.model.dto.request.ReservationSettingUpsertReqDTO;
import com.jzo2o.health.model.dto.response.ReservationDateResDTO;
import com.jzo2o.health.model.dto.response.ReservationSettingResDTO;
import com.jzo2o.health.model.excel.ReservationImportData;
import com.jzo2o.health.service.IReservationSettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @Author whx
 * @Date 2024/12/13 19:47
 */
@Service
@Slf4j
public class ReservationSettingServiceImpl extends ServiceImpl<ReservationSettingMapper, ReservationSetting> implements IReservationSettingService {

    @Override
    public List<ReservationSettingResDTO> getReservationSettingByMonthForAdmin(String date) {

        // select * from rs where order_date like #{date}
        List<ReservationSetting> list = this.lambdaQuery()
                .like(ReservationSetting::getOrderDate, date)
                .list();

        return list.stream().map(rs -> {
                    ReservationSettingResDTO reservationSettingResDTO = BeanUtil.toBean(rs, ReservationSettingResDTO.class);
                    reservationSettingResDTO.setDate(rs.getOrderDate().toString());
                    return reservationSettingResDTO;
                }).collect(Collectors.toList());
    }

    @Override
    public void editNumberByDate(ReservationSettingUpsertReqDTO dto) {
        ReservationSetting rs = this.lambdaQuery()
                .eq(ReservationSetting::getOrderDate, dto.getOrderDate())
                .one();

        if(ObjectUtil.isNull(rs)){
            rs = BeanUtil.toBean(dto, ReservationSetting.class);
            this.save(rs);
            return;
        }

        boolean result = this.lambdaUpdate()
                .eq(ReservationSetting::getOrderDate, dto.getOrderDate())
                .set(ReservationSetting::getNumber, dto.getNumber())
                .update();

        if(!result){
            throw new ForbiddenOperationException("更新失败");
        }
    }


    @Override
    public void upload(MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            // 使用 EasyExcel 读取所有数据
            List<ReservationImportData> dataList = EasyExcel.read(inputStream).head(ReservationImportData.class).sheet().doReadSync();

            // 将数据转换为 ReservationSetting 并保存到数据库
            List<ReservationSetting> collect = dataList.stream().map(rsd -> {
                ReservationSetting rs = BeanUtil.toBean(rsd, ReservationSetting.class);

                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate localDate = LocalDate.parse(rsd.getDate(), formatter);
                rs.setOrderDate(localDate);

                return rs;
            }).collect(Collectors.toList());

            this.saveBatch(collect);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public ReservationDateResDTO getReservationDateByMonthForUser(String month) {

        // select * from rs where order_date like #{month} and number > reservation
        List<ReservationSetting> list = this.lambdaQuery()
                .like(ReservationSetting::getOrderDate, month)
                .apply("number > reservations")
                .list();

        List<String> collect = list.stream().map(ReservationSetting::getOrderDate).map(LocalDate::toString).collect(Collectors.toList());

        return new ReservationDateResDTO(collect);
    }
}
